package discover

import (
	"bytes"
	"encoding/json"
	"fmt"
	logger "gitee.com/zaper/private-logger"
	"gitee.com/zaper/service-center-client/constant"
	"gitee.com/zaper/service-center-client/service/service_info"
	"gitee.com/zaper/service-center-client/util"
	fmkutil "gitee.com/zaper/software-framework/util"
	"os"
	"sync"
)

const (
	discoveryInterface = "/api/v1/service/discovery"
)

var (
	discoverClientManagerOnce   sync.Once
	discoverClientManagerSingle *DiscoverClientManager
)

type DiscoverClientManager struct {
	httpClient *fmkutil.HttpClientManager
}

func GetDiscoverClientManager() *DiscoverClientManager {
	discoverClientManagerOnce.Do(func() {
		discoverClientManagerSingle = &DiscoverClientManager{
			httpClient: fmkutil.NewHttpClientManager(),
		}
	})
	return discoverClientManagerSingle
}

func (discoverClientManager *DiscoverClientManager) GetServiceInfo(serviceName string) []service_info.InstanceInfo {
	request := make(map[string]string)
	request["serviceName"] = serviceName
	rq, err := json.Marshal(request)
	if err != nil {
		logger.Errorf("Marshal request err,err is %s", rq)
		return nil
	}
	registerUrl := fmt.Sprintf("%s%s%s",
		"https://", os.Getenv(constant.ResisterCenterKey), discoveryInterface)
	resp, err := discoverClientManager.httpClient.Post(registerUrl, constant.ContentType, bytes.NewReader(rq))
	if err != nil {
		return nil
	}
	return parseDiscoveryResult(resp)
}

func parseDiscoveryResult(r []byte) []service_info.InstanceInfo {
	response := &util.HttpResponseError{}
	err := json.Unmarshal(r, response)
	if err != nil {
		logger.Errorf("service center read unmarshal discovery response fail")
		return nil
	}
	if response.ErrorCode == 0 {
		instances := parseInstanceInfo(response.ErrorMess)
		return instances
	}
	return nil
}

func parseInstanceInfo(instances interface{}) []service_info.InstanceInfo {
	instanceJson, err := json.Marshal(instances)
	if err != nil {
		return nil
	}
	var s []service_info.InstanceInfo
	err = json.Unmarshal(instanceJson, &s)
	if err != nil {
		return nil
	}
	return s
}
